home *** CD-ROM | disk | FTP | other *** search
- /* XFun to allow rgb image array */
- #include "callback.h"
-
- PixMapHandle DirectPix(long rows,long cols) // create a 16-bit RGBDirect pixmap
- {
- PixMapHandle pixh;
- PixMapPtr pm;
- Ptr pixels;
- pixh = NewPixMap();
- pixels = NewPtrClear(rows*cols*2);
- if(!pixh || !pixels) return(NULL);
-
- pm = *pixh; // don't need to lock. no calls
- pm->pixelType = RGBDirect;
- pm->pixelSize = 16;
- pm->cmpCount = 3;
- pm->cmpSize = 5;
-
- pm->bounds.top = 0;
- pm->bounds.left = 0;
- pm->bounds.bottom = cols;
- pm->bounds.right = rows;
-
- pm->baseAddr = pixels;
- pm->rowBytes = 0x8000 | rows*2; // hi bit flags pixmap/bitmap
- return(pixh);
- }
-
- PicHandle MakePICT(PixMapHandle pixh) // copy pixmap to PICT & dispose pixmap
- {
- PixMapPtr srcpm,dstpm;
- PicHandle thePic;
- CGrafPtr picport,savport;
-
- /* The current grafport will be a text window which is not even a color port.
- Maybe it doesn't matter since the pixmap is never drawn, but it seems
- safer to make a new grafport for the pict.
- This routine may run out of memory since it needs space for the pixmap
- and the PICT at the same time */
-
- picport = (CGrafPtr)NewPtr(sizeof(CGrafPort));
- OpenCPort(picport);
- GetPort(&savport);
- SetPort(picport);
- HLock(pixh);
- srcpm = *pixh;
- thePic = OpenPicture(&srcpm->bounds);
- CopyBits(srcpm,*(picport->portPixMap),&srcpm->bounds,&srcpm->bounds,ditherCopy,0);
- HUnlock(pixh);
- DisposePixMap(pixh); // free up mem as soon as possible
- ClosePicture();
- SetPort(savport);
- CloseCPort(picport);
- DisposPtr(picport);
- return(thePic);
- }
-
- badparm(EXPR arr,funptr callback)
- {
- ErrMsg(" imageRGB(?) array dim?",0,callback);
- FreeExpr(arr,callback);
- }
-
- BOOL imageRGB(extended *retval,funptr callback)
- {
- PixMapHandle pixh;
- EXPR arr;
- extended num,*iptr,*jptr,*rgb;
- long rows,cols,n,zero;
- BOOL isarray;
- short pak,comp,*pix,k;
- long i,j;
-
- MakeParmExpr(0,&arr,callback);
-
- ProbeExpr(arr,&num,&isarray,&rows,callback);
- if(!isarray || !rows)
- {
- badparm(arr,callback);
- return(FALSE);
- }
-
- AddIndex(&arr,&iptr,callback);
- ProbeExpr(arr,&num,&isarray,&cols,callback);
- if(!isarray || !cols)
- {
- badparm(arr,callback);
- return(FALSE);
- }
-
- pixh = DirectPix(rows,cols);
- if(!pixh)
- {
- ErrMsg(" can't alloc pixmap",0,callback);
- FreeExpr(arr,callback);
- return(FALSE);
- }
- pix = (short *)((*pixh)->baseAddr);
-
- AddIndex(&arr,&jptr,callback); /* arr[i,j] is {R,G,B}. Could use GetExprMatrix() to get
- a row at a time but that could be a lot of space. */
- for(i=0;i<rows;i++)
- {
- *jptr = 1;
- for(j=cols-1;j>=0;j--) // "sideways" image[x,y] convention
- {
- if(GetExprMatrix(arr,&rgb,&n,&zero,callback) && zero == 0 && n == 3)
- {
- pak = 0;
- for(k=0; k<3; k++)
- {
- comp = rgb[k] * 31.0;
- if(comp>31 || comp<0) ErrMsg(" RGB component must be 0 to 1",0,callback);
- pak = (pak<<5) | comp;
- }
- DisposPtr(rgb);
- }
- else
- {
- DisposePixMap(pixh);
- badparm(arr,callback); // or some other error came first
- return(FALSE);
- }
- pix[j*rows+i] = pak;
- *jptr += 1.0;
- }
- *iptr += 1.0;
- }
- FreeExpr(arr,callback);
-
- SetPlotPICT(MakePICT(pixh),callback);
- return(FALSE);
- }
-
-
- main(funptr callback)
- {
- AddXfun("imageRGB","rgbarray",&imageRGB,NULL,callback);
- }
-